{
 "cells": [
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "### K 近邻算法\n",
    "\n",
    "K 近邻算法是一种简单且常用的监督学习算法，主要用于分类和回归任务。它的核心思想是：对于一个未知样本，通过计算其与训练集中所有样本的距离，找到距离最近的 K 个样本（即 K 个邻居），然后根据这些邻居的标签或值来预测未知样本的标签或值。\n",
    "\n",
    "主要参数:\n",
    "\n",
    "n_neighbors：K 值，即选择的邻居数量。默认值为 5。\n",
    "\n",
    "weights：邻居的权重。可以是：\n",
    "\n",
    "uniform：所有邻居的权重相同。\n",
    "\n",
    "distance：邻居的权重与距离成反比。\n",
    "\n",
    "优点:\n",
    "\n",
    "简单易用：算法原理简单，易于理解和实现。\n",
    "\n",
    "无需训练：KNN 是一种惰性学习算法，训练阶段仅存储数据，计算在预测阶段进行。\n",
    "\n",
    "适用于多分类问题：天然支持多分类任务。\n",
    "\n",
    "可解释性强：预测结果基于最近的邻居，易于解释。\n",
    "\n",
    "缺点:\n",
    "\n",
    "计算复杂度高：预测时需要计算与所有训练样本的距离，计算量大。\n",
    "\n",
    "对高维数据不友好：在高维空间中，距离度量可能失效（维度灾难）。\n",
    "\n",
    "对噪声敏感：噪声数据或异常值可能影响预测结果。\n",
    "\n",
    "需要特征缩放：KNN 对特征的尺度敏感，通常需要对数据进行标准化或归一化。"
   ],
   "id": "b8921a66ef020cd0"
  },
  {
   "cell_type": "code",
   "id": "82acd9e6d628f2b4",
   "metadata": {
    "collapsed": true,
    "ExecuteTime": {
     "end_time": "2025-01-12T07:33:25.167297Z",
     "start_time": "2025-01-12T07:33:25.161381Z"
    }
   },
   "source": [
    "import pandas as pd\n",
    "from sklearn.model_selection import train_test_split\n",
    "from sklearn.preprocessing import StandardScaler\n",
    "from sklearn.neighbors import KNeighborsClassifier"
   ],
   "outputs": [],
   "execution_count": 91
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "##### 数据读取",
   "id": "10cddf3e9d6b70f7"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-12T07:05:54.543052Z",
     "start_time": "2025-01-12T07:05:44.587613Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 读取数据\n",
    "data = pd.read_csv(\"D:/pythonProject/pythonProject1/pythonProject/data/FBlocation/train.csv\")"
   ],
   "id": "4581d6ada8ce6495",
   "outputs": [],
   "execution_count": 62
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-12T07:05:54.595814Z",
     "start_time": "2025-01-12T07:05:54.543052Z"
    }
   },
   "cell_type": "code",
   "source": [
    "print(data.head(10))\n",
    "print(data.shape)\n",
    "print(data.info())"
   ],
   "id": "689f283e785ea0d0",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "   row_id       x       y  accuracy    time    place_id\n",
      "0       0  0.7941  9.0809        54  470702  8523065625\n",
      "1       1  5.9567  4.7968        13  186555  1757726713\n",
      "2       2  8.3078  7.0407        74  322648  1137537235\n",
      "3       3  7.3665  2.5165        65  704587  6567393236\n",
      "4       4  4.0961  1.1307        31  472130  7440663949\n",
      "5       5  3.8099  1.9586        75  178065  6289802927\n",
      "6       6  6.3336  4.3720        13  666829  9931249544\n",
      "7       7  5.7409  6.7697        85  369002  5662813655\n",
      "8       8  4.3114  6.9410         3  166384  8471780938\n",
      "9       9  6.3414  0.0758        65  400060  1253803156\n",
      "(29118021, 6)\n",
      "<class 'pandas.core.frame.DataFrame'>\n",
      "RangeIndex: 29118021 entries, 0 to 29118020\n",
      "Data columns (total 6 columns):\n",
      " #   Column    Dtype  \n",
      "---  ------    -----  \n",
      " 0   row_id    int64  \n",
      " 1   x         float64\n",
      " 2   y         float64\n",
      " 3   accuracy  int64  \n",
      " 4   time      int64  \n",
      " 5   place_id  int64  \n",
      "dtypes: float64(2), int64(4)\n",
      "memory usage: 1.3 GB\n",
      "None\n"
     ]
    }
   ],
   "execution_count": 63
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "##### 数据预处理",
   "id": "b907a07dee82f114"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-12T07:05:55.221804Z",
     "start_time": "2025-01-12T07:05:54.595814Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 处理数据\n",
    "# 1、缩小数据,查询数据,为了减少计算时间\n",
    "data = data.query(\"x > 1.0 &  x < 1.25 & y > 2.5 & y < 2.75\")\n",
    "print(data.head(10))\n",
    "print(data.shape)\n",
    "print(data.info())"
   ],
   "id": "initial_id",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "      row_id       x       y  accuracy    time    place_id\n",
      "600      600  1.2214  2.7023        17   65380  6683426742\n",
      "957      957  1.1832  2.6891        58  785470  6683426742\n",
      "4345    4345  1.1935  2.6550        11  400082  6889790653\n",
      "4735    4735  1.1452  2.6074        49  514983  6822359752\n",
      "5580    5580  1.0089  2.7287        19  732410  1527921905\n",
      "6090    6090  1.1140  2.6262        11  145507  4000153867\n",
      "6234    6234  1.1449  2.5003        34  316377  3741484405\n",
      "6350    6350  1.0844  2.7436        65   36816  5963693798\n",
      "7468    7468  1.0058  2.5096        66  746766  9076695703\n",
      "8478    8478  1.2015  2.5187        72  690722  3992589015\n",
      "(17710, 6)\n",
      "<class 'pandas.core.frame.DataFrame'>\n",
      "Index: 17710 entries, 600 to 29112154\n",
      "Data columns (total 6 columns):\n",
      " #   Column    Non-Null Count  Dtype  \n",
      "---  ------    --------------  -----  \n",
      " 0   row_id    17710 non-null  int64  \n",
      " 1   x         17710 non-null  float64\n",
      " 2   y         17710 non-null  float64\n",
      " 3   accuracy  17710 non-null  int64  \n",
      " 4   time      17710 non-null  int64  \n",
      " 5   place_id  17710 non-null  int64  \n",
      "dtypes: float64(2), int64(4)\n",
      "memory usage: 968.5 KB\n",
      "None\n"
     ]
    }
   ],
   "execution_count": 64
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-12T07:05:55.248992Z",
     "start_time": "2025-01-12T07:05:55.221804Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 数据集的描述性统计信息，确保无空值，异常值（空值会报错）\n",
    "data.describe()"
   ],
   "id": "3c830eea456598f",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "             row_id             x             y      accuracy           time  \\\n",
       "count  1.771000e+04  17710.000000  17710.000000  17710.000000   17710.000000   \n",
       "mean   1.450569e+07      1.122538      2.632309     82.482101  397551.263128   \n",
       "std    8.353805e+06      0.077086      0.070144    113.613227  234601.097883   \n",
       "min    6.000000e+02      1.000100      2.500100      1.000000     119.000000   \n",
       "25%    7.327816e+06      1.049200      2.573800     25.000000  174069.750000   \n",
       "50%    1.443071e+07      1.123300      2.642300     62.000000  403387.500000   \n",
       "75%    2.163463e+07      1.190500      2.687800     75.000000  602111.750000   \n",
       "max    2.911215e+07      1.249900      2.749900   1004.000000  786218.000000   \n",
       "\n",
       "           place_id  \n",
       "count  1.771000e+04  \n",
       "mean   5.129895e+09  \n",
       "std    2.357399e+09  \n",
       "min    1.012024e+09  \n",
       "25%    3.312464e+09  \n",
       "50%    5.261906e+09  \n",
       "75%    6.766325e+09  \n",
       "max    9.980711e+09  "
      ],
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>row_id</th>\n",
       "      <th>x</th>\n",
       "      <th>y</th>\n",
       "      <th>accuracy</th>\n",
       "      <th>time</th>\n",
       "      <th>place_id</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>count</th>\n",
       "      <td>1.771000e+04</td>\n",
       "      <td>17710.000000</td>\n",
       "      <td>17710.000000</td>\n",
       "      <td>17710.000000</td>\n",
       "      <td>17710.000000</td>\n",
       "      <td>1.771000e+04</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>mean</th>\n",
       "      <td>1.450569e+07</td>\n",
       "      <td>1.122538</td>\n",
       "      <td>2.632309</td>\n",
       "      <td>82.482101</td>\n",
       "      <td>397551.263128</td>\n",
       "      <td>5.129895e+09</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>std</th>\n",
       "      <td>8.353805e+06</td>\n",
       "      <td>0.077086</td>\n",
       "      <td>0.070144</td>\n",
       "      <td>113.613227</td>\n",
       "      <td>234601.097883</td>\n",
       "      <td>2.357399e+09</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>min</th>\n",
       "      <td>6.000000e+02</td>\n",
       "      <td>1.000100</td>\n",
       "      <td>2.500100</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>119.000000</td>\n",
       "      <td>1.012024e+09</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>25%</th>\n",
       "      <td>7.327816e+06</td>\n",
       "      <td>1.049200</td>\n",
       "      <td>2.573800</td>\n",
       "      <td>25.000000</td>\n",
       "      <td>174069.750000</td>\n",
       "      <td>3.312464e+09</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>50%</th>\n",
       "      <td>1.443071e+07</td>\n",
       "      <td>1.123300</td>\n",
       "      <td>2.642300</td>\n",
       "      <td>62.000000</td>\n",
       "      <td>403387.500000</td>\n",
       "      <td>5.261906e+09</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>75%</th>\n",
       "      <td>2.163463e+07</td>\n",
       "      <td>1.190500</td>\n",
       "      <td>2.687800</td>\n",
       "      <td>75.000000</td>\n",
       "      <td>602111.750000</td>\n",
       "      <td>6.766325e+09</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>max</th>\n",
       "      <td>2.911215e+07</td>\n",
       "      <td>1.249900</td>\n",
       "      <td>2.749900</td>\n",
       "      <td>1004.000000</td>\n",
       "      <td>786218.000000</td>\n",
       "      <td>9.980711e+09</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ]
     },
     "execution_count": 65,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 65
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-12T07:05:55.259969Z",
     "start_time": "2025-01-12T07:05:55.248992Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 处理时间的数据，unit设置以秒为单位，把秒转换成日期格式\n",
    "time_value = pd.to_datetime(data['time'], unit='s')\n",
    "print(time_value.head(10))  # 用于查看 time_value 的前 10 行数据"
   ],
   "id": "b095282c0adc8dd8",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "600    1970-01-01 18:09:40\n",
      "957    1970-01-10 02:11:10\n",
      "4345   1970-01-05 15:08:02\n",
      "4735   1970-01-06 23:03:03\n",
      "5580   1970-01-09 11:26:50\n",
      "6090   1970-01-02 16:25:07\n",
      "6234   1970-01-04 15:52:57\n",
      "6350   1970-01-01 10:13:36\n",
      "7468   1970-01-09 15:26:06\n",
      "8478   1970-01-08 23:52:02\n",
      "Name: time, dtype: datetime64[ns]\n"
     ]
    }
   ],
   "execution_count": 66
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-12T07:05:55.265412Z",
     "start_time": "2025-01-12T07:05:55.260975Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 将 time_value 转换为 Pandas 的 DatetimeIndex 对象，DatetimeIndex 是 Pandas 中用于存储日期时间数据的索引类型\n",
    "time_value = pd.DatetimeIndex(time_value)\n",
    "# 查看 time_value 中的前 10 个元素\n",
    "print(time_value[0:10])"
   ],
   "id": "5e918edd24162a12",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "DatetimeIndex(['1970-01-01 18:09:40', '1970-01-10 02:11:10',\n",
      "               '1970-01-05 15:08:02', '1970-01-06 23:03:03',\n",
      "               '1970-01-09 11:26:50', '1970-01-02 16:25:07',\n",
      "               '1970-01-04 15:52:57', '1970-01-01 10:13:36',\n",
      "               '1970-01-09 15:26:06', '1970-01-08 23:52:02'],\n",
      "              dtype='datetime64[ns]', name='time', freq=None)\n"
     ]
    }
   ],
   "execution_count": 67
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-12T07:05:55.270884Z",
     "start_time": "2025-01-12T07:05:55.265412Z"
    }
   },
   "cell_type": "code",
   "source": "data.shape# 获取数据维度信息",
   "id": "ce8be37b1a591c94",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(17710, 6)"
      ]
     },
     "execution_count": 68,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 68
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-12T07:05:55.291458Z",
     "start_time": "2025-01-12T07:05:55.270884Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 构造一些特征，执行的警告是因为我们的操作是复制，loc是直接放入\n",
    "print(type(data))\n",
    "# 从 time_value 中提取日期时间信息（如日、小时、星期几），并将这些信息作为新列添加到 data 中\n",
    "# data['day'] = time_value.day\n",
    "# data['hour'] = time_value.hour\n",
    "# data['weekday'] = time_value.weekday\n",
    "#日期，是否是周末，小时对于个人行为的影响是较大的(例如吃饭时间去饭店，看电影时间去电影院等),所以才做下面的处理\n",
    "data.insert(data.shape[1], 'day', time_value.day) #data.shape[1]是代表插入到最后的意思,一个月的哪一天\n",
    "data.insert(data.shape[1], 'hour', time_value.hour)#是否去一个地方打卡，早上，中午，晚上是有影响的\n",
    "data.insert(data.shape[1], 'weekday', time_value.weekday) #0代表周一，6代表周日，星期几\n",
    "# data.shape 是 Pandas DataFrame 的一个属性，返回一个元组 (行数, 列数)。\n",
    "# data.shape[0] 表示行数（3）。\n",
    "# data.shape[1] 表示列数（2）。\n",
    "# data.shape[1] 返回的是 data 的当前列数\n",
    "# 把时间戳特征删除\n",
    "data = data.drop(['time'], axis=1)# 从 data 中删除名为 time 的列（axis=0表示删除行（默认值），axis=1表示删除列）\n",
    "data.head()# 默认返回前 5 行数据，查看数据的最后 5 行，可以使用 data.tail()"
   ],
   "id": "b5bce29a1015e4c2",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'pandas.core.frame.DataFrame'>\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "      row_id       x       y  accuracy    place_id  day  hour  weekday\n",
       "600      600  1.2214  2.7023        17  6683426742    1    18        3\n",
       "957      957  1.1832  2.6891        58  6683426742   10     2        5\n",
       "4345    4345  1.1935  2.6550        11  6889790653    5    15        0\n",
       "4735    4735  1.1452  2.6074        49  6822359752    6    23        1\n",
       "5580    5580  1.0089  2.7287        19  1527921905    9    11        4"
      ],
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>row_id</th>\n",
       "      <th>x</th>\n",
       "      <th>y</th>\n",
       "      <th>accuracy</th>\n",
       "      <th>place_id</th>\n",
       "      <th>day</th>\n",
       "      <th>hour</th>\n",
       "      <th>weekday</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>600</th>\n",
       "      <td>600</td>\n",
       "      <td>1.2214</td>\n",
       "      <td>2.7023</td>\n",
       "      <td>17</td>\n",
       "      <td>6683426742</td>\n",
       "      <td>1</td>\n",
       "      <td>18</td>\n",
       "      <td>3</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>957</th>\n",
       "      <td>957</td>\n",
       "      <td>1.1832</td>\n",
       "      <td>2.6891</td>\n",
       "      <td>58</td>\n",
       "      <td>6683426742</td>\n",
       "      <td>10</td>\n",
       "      <td>2</td>\n",
       "      <td>5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4345</th>\n",
       "      <td>4345</td>\n",
       "      <td>1.1935</td>\n",
       "      <td>2.6550</td>\n",
       "      <td>11</td>\n",
       "      <td>6889790653</td>\n",
       "      <td>5</td>\n",
       "      <td>15</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4735</th>\n",
       "      <td>4735</td>\n",
       "      <td>1.1452</td>\n",
       "      <td>2.6074</td>\n",
       "      <td>49</td>\n",
       "      <td>6822359752</td>\n",
       "      <td>6</td>\n",
       "      <td>23</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5580</th>\n",
       "      <td>5580</td>\n",
       "      <td>1.0089</td>\n",
       "      <td>2.7287</td>\n",
       "      <td>19</td>\n",
       "      <td>1527921905</td>\n",
       "      <td>9</td>\n",
       "      <td>11</td>\n",
       "      <td>4</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ]
     },
     "execution_count": 69,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 69
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-12T07:05:55.305764Z",
     "start_time": "2025-01-12T07:05:55.291458Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 周一至周日，对应weekday的值为0至6\n",
    "# 创建一个 Period 对象\n",
    "per = pd.Period('2025-01-12 18:00', 'h')\n",
    "per.weekday# 查看2025年1月12日是周几"
   ],
   "id": "400c7f166f2da6a4",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "6"
      ]
     },
     "execution_count": 70,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 70
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-12T07:05:55.329353Z",
     "start_time": "2025-01-12T07:05:55.305764Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 数据集的描述性统计信息，确保无空值，异常值（空值会报错）\n",
    "data.describe()"
   ],
   "id": "1ef8a85e79d2b6d5",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "             row_id             x             y      accuracy      place_id  \\\n",
       "count  1.771000e+04  17710.000000  17710.000000  17710.000000  1.771000e+04   \n",
       "mean   1.450569e+07      1.122538      2.632309     82.482101  5.129895e+09   \n",
       "std    8.353805e+06      0.077086      0.070144    113.613227  2.357399e+09   \n",
       "min    6.000000e+02      1.000100      2.500100      1.000000  1.012024e+09   \n",
       "25%    7.327816e+06      1.049200      2.573800     25.000000  3.312464e+09   \n",
       "50%    1.443071e+07      1.123300      2.642300     62.000000  5.261906e+09   \n",
       "75%    2.163463e+07      1.190500      2.687800     75.000000  6.766325e+09   \n",
       "max    2.911215e+07      1.249900      2.749900   1004.000000  9.980711e+09   \n",
       "\n",
       "                day          hour       weekday  \n",
       "count  17710.000000  17710.000000  17710.000000  \n",
       "mean       5.101863     11.485545      3.092377  \n",
       "std        2.709287      6.932195      1.680218  \n",
       "min        1.000000      0.000000      0.000000  \n",
       "25%        3.000000      6.000000      2.000000  \n",
       "50%        5.000000     12.000000      3.000000  \n",
       "75%        7.000000     17.000000      4.000000  \n",
       "max       10.000000     23.000000      6.000000  "
      ],
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>row_id</th>\n",
       "      <th>x</th>\n",
       "      <th>y</th>\n",
       "      <th>accuracy</th>\n",
       "      <th>place_id</th>\n",
       "      <th>day</th>\n",
       "      <th>hour</th>\n",
       "      <th>weekday</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>count</th>\n",
       "      <td>1.771000e+04</td>\n",
       "      <td>17710.000000</td>\n",
       "      <td>17710.000000</td>\n",
       "      <td>17710.000000</td>\n",
       "      <td>1.771000e+04</td>\n",
       "      <td>17710.000000</td>\n",
       "      <td>17710.000000</td>\n",
       "      <td>17710.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>mean</th>\n",
       "      <td>1.450569e+07</td>\n",
       "      <td>1.122538</td>\n",
       "      <td>2.632309</td>\n",
       "      <td>82.482101</td>\n",
       "      <td>5.129895e+09</td>\n",
       "      <td>5.101863</td>\n",
       "      <td>11.485545</td>\n",
       "      <td>3.092377</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>std</th>\n",
       "      <td>8.353805e+06</td>\n",
       "      <td>0.077086</td>\n",
       "      <td>0.070144</td>\n",
       "      <td>113.613227</td>\n",
       "      <td>2.357399e+09</td>\n",
       "      <td>2.709287</td>\n",
       "      <td>6.932195</td>\n",
       "      <td>1.680218</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>min</th>\n",
       "      <td>6.000000e+02</td>\n",
       "      <td>1.000100</td>\n",
       "      <td>2.500100</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>1.012024e+09</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>25%</th>\n",
       "      <td>7.327816e+06</td>\n",
       "      <td>1.049200</td>\n",
       "      <td>2.573800</td>\n",
       "      <td>25.000000</td>\n",
       "      <td>3.312464e+09</td>\n",
       "      <td>3.000000</td>\n",
       "      <td>6.000000</td>\n",
       "      <td>2.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>50%</th>\n",
       "      <td>1.443071e+07</td>\n",
       "      <td>1.123300</td>\n",
       "      <td>2.642300</td>\n",
       "      <td>62.000000</td>\n",
       "      <td>5.261906e+09</td>\n",
       "      <td>5.000000</td>\n",
       "      <td>12.000000</td>\n",
       "      <td>3.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>75%</th>\n",
       "      <td>2.163463e+07</td>\n",
       "      <td>1.190500</td>\n",
       "      <td>2.687800</td>\n",
       "      <td>75.000000</td>\n",
       "      <td>6.766325e+09</td>\n",
       "      <td>7.000000</td>\n",
       "      <td>17.000000</td>\n",
       "      <td>4.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>max</th>\n",
       "      <td>2.911215e+07</td>\n",
       "      <td>1.249900</td>\n",
       "      <td>2.749900</td>\n",
       "      <td>1004.000000</td>\n",
       "      <td>9.980711e+09</td>\n",
       "      <td>10.000000</td>\n",
       "      <td>23.000000</td>\n",
       "      <td>6.000000</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ]
     },
     "execution_count": 71,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 71
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-12T07:05:55.341702Z",
     "start_time": "2025-01-12T07:05:55.329353Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 对 data 中的数据按 place_id 列进行分组，并统计每个 place_id 出现的次数, place_id 成为索引（index）\n",
    "place_count = data.groupby('place_id').count()\n",
    "place_count"
   ],
   "id": "785b041adb9f4479",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "            row_id     x     y  accuracy   day  hour  weekday\n",
       "place_id                                                     \n",
       "1012023972       1     1     1         1     1     1        1\n",
       "1057182134       1     1     1         1     1     1        1\n",
       "1059958036       3     3     3         3     3     3        3\n",
       "1085266789       1     1     1         1     1     1        1\n",
       "1097200869    1044  1044  1044      1044  1044  1044     1044\n",
       "...            ...   ...   ...       ...   ...   ...      ...\n",
       "9904182060       1     1     1         1     1     1        1\n",
       "9915093501       1     1     1         1     1     1        1\n",
       "9946198589       1     1     1         1     1     1        1\n",
       "9950190890       1     1     1         1     1     1        1\n",
       "9980711012       5     5     5         5     5     5        5\n",
       "\n",
       "[805 rows x 7 columns]"
      ],
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>row_id</th>\n",
       "      <th>x</th>\n",
       "      <th>y</th>\n",
       "      <th>accuracy</th>\n",
       "      <th>day</th>\n",
       "      <th>hour</th>\n",
       "      <th>weekday</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>place_id</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>1012023972</th>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1057182134</th>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1059958036</th>\n",
       "      <td>3</td>\n",
       "      <td>3</td>\n",
       "      <td>3</td>\n",
       "      <td>3</td>\n",
       "      <td>3</td>\n",
       "      <td>3</td>\n",
       "      <td>3</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1085266789</th>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1097200869</th>\n",
       "      <td>1044</td>\n",
       "      <td>1044</td>\n",
       "      <td>1044</td>\n",
       "      <td>1044</td>\n",
       "      <td>1044</td>\n",
       "      <td>1044</td>\n",
       "      <td>1044</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9904182060</th>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9915093501</th>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9946198589</th>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9950190890</th>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9980711012</th>\n",
       "      <td>5</td>\n",
       "      <td>5</td>\n",
       "      <td>5</td>\n",
       "      <td>5</td>\n",
       "      <td>5</td>\n",
       "      <td>5</td>\n",
       "      <td>5</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>805 rows × 7 columns</p>\n",
       "</div>"
      ]
     },
     "execution_count": 72,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 72
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-12T07:05:55.358956Z",
     "start_time": "2025-01-12T07:05:55.341702Z"
    }
   },
   "cell_type": "code",
   "source": "place_count.describe() #打卡地点总计805个，50%打卡小于2次",
   "id": "7014f22c1d0df314",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "            row_id            x            y     accuracy          day  \\\n",
       "count   805.000000   805.000000   805.000000   805.000000   805.000000   \n",
       "mean     22.000000    22.000000    22.000000    22.000000    22.000000   \n",
       "std      88.955632    88.955632    88.955632    88.955632    88.955632   \n",
       "min       1.000000     1.000000     1.000000     1.000000     1.000000   \n",
       "25%       1.000000     1.000000     1.000000     1.000000     1.000000   \n",
       "50%       2.000000     2.000000     2.000000     2.000000     2.000000   \n",
       "75%       5.000000     5.000000     5.000000     5.000000     5.000000   \n",
       "max    1044.000000  1044.000000  1044.000000  1044.000000  1044.000000   \n",
       "\n",
       "              hour      weekday  \n",
       "count   805.000000   805.000000  \n",
       "mean     22.000000    22.000000  \n",
       "std      88.955632    88.955632  \n",
       "min       1.000000     1.000000  \n",
       "25%       1.000000     1.000000  \n",
       "50%       2.000000     2.000000  \n",
       "75%       5.000000     5.000000  \n",
       "max    1044.000000  1044.000000  "
      ],
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>row_id</th>\n",
       "      <th>x</th>\n",
       "      <th>y</th>\n",
       "      <th>accuracy</th>\n",
       "      <th>day</th>\n",
       "      <th>hour</th>\n",
       "      <th>weekday</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>count</th>\n",
       "      <td>805.000000</td>\n",
       "      <td>805.000000</td>\n",
       "      <td>805.000000</td>\n",
       "      <td>805.000000</td>\n",
       "      <td>805.000000</td>\n",
       "      <td>805.000000</td>\n",
       "      <td>805.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>mean</th>\n",
       "      <td>22.000000</td>\n",
       "      <td>22.000000</td>\n",
       "      <td>22.000000</td>\n",
       "      <td>22.000000</td>\n",
       "      <td>22.000000</td>\n",
       "      <td>22.000000</td>\n",
       "      <td>22.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>std</th>\n",
       "      <td>88.955632</td>\n",
       "      <td>88.955632</td>\n",
       "      <td>88.955632</td>\n",
       "      <td>88.955632</td>\n",
       "      <td>88.955632</td>\n",
       "      <td>88.955632</td>\n",
       "      <td>88.955632</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>min</th>\n",
       "      <td>1.000000</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>1.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>25%</th>\n",
       "      <td>1.000000</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>1.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>50%</th>\n",
       "      <td>2.000000</td>\n",
       "      <td>2.000000</td>\n",
       "      <td>2.000000</td>\n",
       "      <td>2.000000</td>\n",
       "      <td>2.000000</td>\n",
       "      <td>2.000000</td>\n",
       "      <td>2.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>75%</th>\n",
       "      <td>5.000000</td>\n",
       "      <td>5.000000</td>\n",
       "      <td>5.000000</td>\n",
       "      <td>5.000000</td>\n",
       "      <td>5.000000</td>\n",
       "      <td>5.000000</td>\n",
       "      <td>5.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>max</th>\n",
       "      <td>1044.000000</td>\n",
       "      <td>1044.000000</td>\n",
       "      <td>1044.000000</td>\n",
       "      <td>1044.000000</td>\n",
       "      <td>1044.000000</td>\n",
       "      <td>1044.000000</td>\n",
       "      <td>1044.000000</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ]
     },
     "execution_count": 73,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 73
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-12T07:05:55.363740Z",
     "start_time": "2025-01-12T07:05:55.358956Z"
    }
   },
   "cell_type": "code",
   "source": "place_count.index# 使用 .index 查看 DataFrame 的索引",
   "id": "808a37af944c0d2",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Index([1012023972, 1057182134, 1059958036, 1085266789, 1097200869, 1099012307,\n",
       "       1104074781, 1114479687, 1131595401, 1133878283,\n",
       "       ...\n",
       "       9806043737, 9809476069, 9842354050, 9872492170, 9898108947, 9904182060,\n",
       "       9915093501, 9946198589, 9950190890, 9980711012],\n",
       "      dtype='int64', name='place_id', length=805)"
      ]
     },
     "execution_count": 74,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 74
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-12T07:05:55.376267Z",
     "start_time": "2025-01-12T07:05:55.363740Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 把index变为0,1,2，3,4,5,6这种效果，从零开始排，原来的index是place_id (如果不想保留原来的索引，可以设置 drop=True)\n",
    "#只选择去的人大于3的数据，认为1,2,3的是噪音，这个地方去的人很少，不用推荐给其他人\n",
    "tf = place_count[place_count.row_id > 3].reset_index()\n",
    "tf  #剩余的签到地点"
   ],
   "id": "b112af7d562fb963",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "       place_id  row_id     x     y  accuracy   day  hour  weekday\n",
       "0    1097200869    1044  1044  1044      1044  1044  1044     1044\n",
       "1    1228935308     120   120   120       120   120   120      120\n",
       "2    1267801529      58    58    58        58    58    58       58\n",
       "3    1278040507      15    15    15        15    15    15       15\n",
       "4    1285051622      21    21    21        21    21    21       21\n",
       "..          ...     ...   ...   ...       ...   ...   ...      ...\n",
       "234  9741307878       5     5     5         5     5     5        5\n",
       "235  9753855529      21    21    21        21    21    21       21\n",
       "236  9806043737       6     6     6         6     6     6        6\n",
       "237  9809476069      23    23    23        23    23    23       23\n",
       "238  9980711012       5     5     5         5     5     5        5\n",
       "\n",
       "[239 rows x 8 columns]"
      ],
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>place_id</th>\n",
       "      <th>row_id</th>\n",
       "      <th>x</th>\n",
       "      <th>y</th>\n",
       "      <th>accuracy</th>\n",
       "      <th>day</th>\n",
       "      <th>hour</th>\n",
       "      <th>weekday</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1097200869</td>\n",
       "      <td>1044</td>\n",
       "      <td>1044</td>\n",
       "      <td>1044</td>\n",
       "      <td>1044</td>\n",
       "      <td>1044</td>\n",
       "      <td>1044</td>\n",
       "      <td>1044</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1228935308</td>\n",
       "      <td>120</td>\n",
       "      <td>120</td>\n",
       "      <td>120</td>\n",
       "      <td>120</td>\n",
       "      <td>120</td>\n",
       "      <td>120</td>\n",
       "      <td>120</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>1267801529</td>\n",
       "      <td>58</td>\n",
       "      <td>58</td>\n",
       "      <td>58</td>\n",
       "      <td>58</td>\n",
       "      <td>58</td>\n",
       "      <td>58</td>\n",
       "      <td>58</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>1278040507</td>\n",
       "      <td>15</td>\n",
       "      <td>15</td>\n",
       "      <td>15</td>\n",
       "      <td>15</td>\n",
       "      <td>15</td>\n",
       "      <td>15</td>\n",
       "      <td>15</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>1285051622</td>\n",
       "      <td>21</td>\n",
       "      <td>21</td>\n",
       "      <td>21</td>\n",
       "      <td>21</td>\n",
       "      <td>21</td>\n",
       "      <td>21</td>\n",
       "      <td>21</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>234</th>\n",
       "      <td>9741307878</td>\n",
       "      <td>5</td>\n",
       "      <td>5</td>\n",
       "      <td>5</td>\n",
       "      <td>5</td>\n",
       "      <td>5</td>\n",
       "      <td>5</td>\n",
       "      <td>5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>235</th>\n",
       "      <td>9753855529</td>\n",
       "      <td>21</td>\n",
       "      <td>21</td>\n",
       "      <td>21</td>\n",
       "      <td>21</td>\n",
       "      <td>21</td>\n",
       "      <td>21</td>\n",
       "      <td>21</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>236</th>\n",
       "      <td>9806043737</td>\n",
       "      <td>6</td>\n",
       "      <td>6</td>\n",
       "      <td>6</td>\n",
       "      <td>6</td>\n",
       "      <td>6</td>\n",
       "      <td>6</td>\n",
       "      <td>6</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>237</th>\n",
       "      <td>9809476069</td>\n",
       "      <td>23</td>\n",
       "      <td>23</td>\n",
       "      <td>23</td>\n",
       "      <td>23</td>\n",
       "      <td>23</td>\n",
       "      <td>23</td>\n",
       "      <td>23</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>238</th>\n",
       "      <td>9980711012</td>\n",
       "      <td>5</td>\n",
       "      <td>5</td>\n",
       "      <td>5</td>\n",
       "      <td>5</td>\n",
       "      <td>5</td>\n",
       "      <td>5</td>\n",
       "      <td>5</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>239 rows × 8 columns</p>\n",
       "</div>"
      ]
     },
     "execution_count": 75,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 75
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-12T07:05:55.383639Z",
     "start_time": "2025-01-12T07:05:55.376267Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 根据设定的地点目标值，对原本的样本进行过滤\n",
    "# isin可以过滤某一列要在一组值\n",
    "# 从 data 中筛选出 place_id 列的值存在于 tf.place_id 中的行\n",
    "data = data[data['place_id'].isin(tf.place_id)]\n",
    "# data['place_id'].isin(tf.place_id)返回一个布尔 Series，表示 data 中每行的 place_id 是否在 tf.place_id 中\n",
    "# data[data['place_id'].isin(tf.place_id)] 根据布尔 Series 筛选出 data 中满足条件的行\n",
    "data.shape"
   ],
   "id": "db161f92e414085c",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(16918, 8)"
      ]
     },
     "execution_count": 76,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 76
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-12T07:05:55.389538Z",
     "start_time": "2025-01-12T07:05:55.383639Z"
    }
   },
   "cell_type": "code",
   "source": "print(data)",
   "id": "b619ad29f3021a22",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "            row_id       x       y  accuracy    place_id  day  hour  weekday\n",
      "600            600  1.2214  2.7023        17  6683426742    1    18        3\n",
      "957            957  1.1832  2.6891        58  6683426742   10     2        5\n",
      "4345          4345  1.1935  2.6550        11  6889790653    5    15        0\n",
      "4735          4735  1.1452  2.6074        49  6822359752    6    23        1\n",
      "5580          5580  1.0089  2.7287        19  1527921905    9    11        4\n",
      "...            ...     ...     ...       ...         ...  ...   ...      ...\n",
      "29100203  29100203  1.0129  2.6775        12  3312463746    1    10        3\n",
      "29108443  29108443  1.1474  2.6840        36  3533177779    7    23        2\n",
      "29109993  29109993  1.0240  2.7238        62  6424972551    8    15        3\n",
      "29111539  29111539  1.2032  2.6796        87  3533177779    4     0        6\n",
      "29112154  29112154  1.1070  2.5419       178  4932578245    8    23        3\n",
      "\n",
      "[16918 rows x 8 columns]\n"
     ]
    }
   ],
   "execution_count": 77
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-12T07:05:55.396781Z",
     "start_time": "2025-01-12T07:05:55.389538Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 取出数据当中的特征值和目标值\n",
    "y = data['place_id']\n",
    "# 删除目标值，保留特征值，\n",
    "x = data.drop(['place_id'], axis=1)\n",
    "# 删除无用的特征值\n",
    "x = x.drop(['row_id'], axis=1)\n",
    "print(x.shape)\n",
    "print(x.columns)"
   ],
   "id": "ed2433d6ace85780",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(16918, 6)\n",
      "Index(['x', 'y', 'accuracy', 'day', 'hour', 'weekday'], dtype='object')\n"
     ]
    }
   ],
   "execution_count": 78
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-12T07:05:55.414108Z",
     "start_time": "2025-01-12T07:05:55.396781Z"
    }
   },
   "cell_type": "code",
   "source": "print(y)",
   "id": "e7d6b7cf8b78f771",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "600         6683426742\n",
      "957         6683426742\n",
      "4345        6889790653\n",
      "4735        6822359752\n",
      "5580        1527921905\n",
      "               ...    \n",
      "29100203    3312463746\n",
      "29108443    3533177779\n",
      "29109993    6424972551\n",
      "29111539    3533177779\n",
      "29112154    4932578245\n",
      "Name: place_id, Length: 16918, dtype: int64\n"
     ]
    }
   ],
   "execution_count": 79
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "",
   "id": "949aeb099d05a689"
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "##### 数据训练及测试",
   "id": "195670013c3a1be7"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-12T07:06:16.911816Z",
     "start_time": "2025-01-12T07:06:16.895633Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 进行数据的分割训练集合测试集\n",
    "# train_test_split() 是 Scikit-learn 中用于划分数据集的函数，将数据集随机划分为训练集和测试集\n",
    "# test_size=0.25：指定测试集的比例为 25%（即训练集占 75%）\n",
    "# random_state=1：设置随机种子，确保每次运行代码时划分结果一致。\n",
    "\n",
    "# x：特征矩阵，包含所有特征列。\n",
    "# y：目标变量，包含每个样本的目标值。\n",
    "\n",
    "# x_train：训练集的特征矩阵。\n",
    "# x_test：测试集的特征矩阵。\n",
    "# y_train：训练集的目标变量。\n",
    "# y_test：测试集的目标变量。\n",
    "\n",
    "x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.25, random_state=1)\n",
    "\n",
    "# 特征工程（标准化）,下面 3 行注释，一开始我们不进行标准化，看下效果，目标值要不要标准化？\n",
    "# 创建一个 StandardScaler 对象 std。该对象可以用于对数据进行标准化处理。\n",
    "std = StandardScaler()\n",
    "\n",
    "# 对测试集和训练集的特征值进行标准化,服务于knn fit\n",
    "# fit 拟合数据：计算 x_train 的均值和标准差。\n",
    "# transform 转换数据：使用计算出的均值和标准差对 x_train 进行标准化。\n",
    "x_train = std.fit_transform(x_train)# 使用fit_transform()，一步完成 fit() 和 transform()\n",
    "# transform返回的是copy，不在原有的输入对象中去修改\n",
    "# print(id(x_test))\n",
    "print(std.mean_)\n",
    "print(std.var_)"
   ],
   "id": "f014a89557a6e2e0",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[ 1.12295735  2.63237278 81.34938525  5.10064628 11.44293821  3.10135561]\n",
      "[5.98489138e-03 4.86857391e-03 1.19597480e+04 7.32837915e+00\n",
      " 4.83742660e+01 2.81838404e+00]\n"
     ]
    }
   ],
   "execution_count": 85
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-12T07:06:18.586218Z",
     "start_time": "2025-01-12T07:06:18.566097Z"
    }
   },
   "cell_type": "code",
   "source": [
    "x_test = std.transform(x_test) \n",
    "# print(id(x_test))# 地址发生变化\n",
    "print(std.mean_)# 均值不变\n",
    "print(std.var_)# 方差不变\n",
    "# transform 后均值和方差不变，说明 transfrom 不再对测试集进行均值和方差的计算，而是利用训练集的均值和方差，对测试集进行标准化"
   ],
   "id": "fb24c26b0e3b8c01",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[ 1.12295735  2.63237278 81.34938525  5.10064628 11.44293821  3.10135561]\n",
      "[5.98489138e-03 4.86857391e-03 1.19597480e+04 7.32837915e+00\n",
      " 4.83742660e+01 2.81838404e+00]\n"
     ]
    }
   ],
   "execution_count": 86
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-12T07:06:49.273043Z",
     "start_time": "2025-01-12T07:06:49.268878Z"
    }
   },
   "cell_type": "code",
   "source": "x_train.shape",
   "id": "367801694ef22dd6",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(12688, 6)"
      ]
     },
     "execution_count": 87,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 87
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-12T07:10:10.429246Z",
     "start_time": "2025-01-12T07:10:10.416651Z"
    }
   },
   "cell_type": "code",
   "source": "x_test.shape",
   "id": "1d67991d44d55e3d",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(4230, 6)"
      ]
     },
     "execution_count": 88,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 88
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-12T07:47:49.237083Z",
     "start_time": "2025-01-12T07:47:49.028293Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 进行算法流程 \n",
    "# 创建一个 K 近邻分类器（K-Nearest Neighbors Classifier），并设置近邻数 n_neighbors=6（即设置 K 值为 6，即使用 6 个最近邻居进行分类）。\n",
    "# 可以通过设置n_neighbors=5，来调整结果好坏\n",
    "knn = KNeighborsClassifier(n_neighbors=7)# 测试发现 K 设置为 7 时效果比 6 更优\n",
    "\n",
    "# KNN 是一种惰性学习算法（lazy learning），在训练阶段不会进行任何计算，而是将训练集的特征值和目标值放入到内存中，等到预测阶段再根据存储的数据进行计算。\n",
    "\n",
    "knn.fit(x_train, y_train)# 使用 x_train 和 y_train 训练 KNN 模型，将训练数据 x_train 和标签 y_train 存储在模型中\n",
    "\n",
    "# 得出预测结果\n",
    "# 使用训练好的 K 近邻分类器（KNN）对测试集 x_test 进行预测，并将预测结果存储在 y_predict 中。\n",
    "# predict() 的具体作用是：\n",
    "#   对每个测试样本，找到训练集中距离最近的 K 个邻居。\n",
    "#   根据这 K 个邻居的标签，通过投票决定测试样本的标签。\n",
    "y_predict = knn.predict(x_test)# 返回值类型为numpy.ndarray\n",
    "print(\"预测的目标签到位置为：\", y_predict[0:10])"
   ],
   "id": "590e6f592ff92fbc",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "预测的目标签到位置为： [1913341282 1097200869 6097504486 9632980559 6424972551 4022692381\n",
      " 8048985799 6683426742 1435128522 3312463746]\n"
     ]
    }
   ],
   "execution_count": 106
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-12T07:49:32.034578Z",
     "start_time": "2025-01-12T07:49:31.833365Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 得出准确率,是评估指标\n",
    "# X_test：测试集的特征矩阵，形状为 (n_samples, n_features)。\n",
    "# y_test：测试集的真实标签，形状为 (n_samples,)\n",
    "accuracy = knn.score(x_test, y_test)\n",
    "print(\"预测的准确率:\", accuracy)\n",
    "# print(y_predict)\n",
    "# y_test"
   ],
   "id": "b70d8b2dccd9fd81",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "预测的准确率: 0.48439716312056735\n"
     ]
    }
   ],
   "execution_count": 107
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "### 调超参的方法，网格搜索\n",
    "\n",
    "网格搜索（Grid Search） 是一种用于超参数调优的方法，它通过遍历给定的参数组合，找到使模型性能最优的参数。\n",
    "\n",
    "在机器学习中，模型的性能往往依赖于超参数的选择（如 KNN 中的 n_neighbors，SVM 中的 C 和 gamma 等）。\n",
    "\n",
    "网格搜索的作用是：\n",
    "\n",
    "    遍历所有可能的参数组合。\n",
    "\n",
    "    通过交叉验证评估每组参数的性能。\n",
    "\n",
    "    选择性能最优的参数组合。\n",
    "    \n",
    "网格搜索的步骤\n",
    "\n",
    "    定义参数网格：\n",
    "\n",
    "        列出需要调优的参数及其候选值。\n",
    "\n",
    "        例如，对于 KNN，可以定义 n_neighbors 的候选值为 [3, 5, 7]。\n",
    "\n",
    "    遍历参数组合：\n",
    "\n",
    "        网格搜索会遍历所有可能的参数组合。\n",
    "\n",
    "        例如，如果有两个参数，每个参数有 3 个候选值，则共有 9 种组合。\n",
    "\n",
    "    交叉验证：\n",
    "\n",
    "        对每组参数组合，使用交叉验证评估模型性能。\n",
    "\n",
    "        交叉验证可以减少模型评估的方差，提高结果的可靠性。\n",
    "\n",
    "    选择最优参数：\n",
    "\n",
    "        根据交叉验证的结果，选择性能最优的参数组合。\n",
    "    \n",
    "Scikit-learn 提供了 GridSearchCV 类来实现网格搜索。"
   ],
   "id": "8b24f2b4322f4a2d"
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "",
   "id": "44e5ca6d39681fbc"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-12T08:10:05.290740Z",
     "start_time": "2025-01-12T08:10:05.282111Z"
    }
   },
   "cell_type": "code",
   "source": "from sklearn.model_selection import GridSearchCV",
   "id": "9a6a0433c2fc2da5",
   "outputs": [],
   "execution_count": 108
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-12T08:31:33.870082Z",
     "start_time": "2025-01-12T08:31:26.101007Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 构造一些参数（超参）的值进行搜索\n",
    "\n",
    "# n_neighbors 参数，即 K 值\n",
    "# weights 参数用于控制邻居标签对预测结果的贡献方式：\n",
    "#    uniform：所有邻居的权重相同，即每个邻居的标签对预测结果的贡献相等\n",
    "#    distance：邻居的权重与距离成反比，即距离越近的邻居对预测结果的贡献越大\n",
    "param = {\"n_neighbors\": [8, 9, 10, 11, 12, 13, 14, 15],'weights':['uniform', 'distance']}\n",
    "\n",
    "# 创建一个 网格搜索（Grid Search） 对象，用于对 K 近邻分类器（KNN）进行超参数调优。\n",
    "# 进行网格搜索，cv=3是3折交叉验证，用其中2折训练，1折验证\n",
    "gc = GridSearchCV(knn, param_grid=param, cv=3)\n",
    "\n",
    "# 使用训练数据 x_train 和对应的标签 y_train 来运行网格搜索（Grid Search），以找到最优的超参数组合。\n",
    "# 将传入的x_train再分为训练集，验证集\n",
    "# fit() 将：\n",
    "#    遍历所有可能的参数组合。\n",
    "#    对每组参数组合，使用交叉验证评估模型性能。\n",
    "#    选择性能最优的参数组合。\n",
    "gc.fit(x_train, y_train) "
   ],
   "id": "611329da8f9cc198",
   "outputs": [],
   "execution_count": null
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-12T08:48:02.905365Z",
     "start_time": "2025-01-12T08:48:02.789215Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 预测准确率\n",
    "# 获取最优参数：\n",
    "#    通过 best_params_ 属性获取最优参数组合。\n",
    "#   通过 best_score_ 属性获取最优参数组合的交叉验证得分。\n",
    "print(\"在测试集上准确率：\", gc.score(x_test, y_test))\n",
    "print(\"在交叉验证当中最好的结果：\", gc.best_score_) #最好的结果"
   ],
   "id": "b312ee2f9e891e18",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "在测试集上准确率： 0.49763593380614657\n",
      "在交叉验证当中最好的结果： 0.4816362349278435\n"
     ]
    }
   ],
   "execution_count": 119
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-12T08:48:34.936011Z",
     "start_time": "2025-01-12T08:48:34.918668Z"
    }
   },
   "cell_type": "code",
   "source": "print(\"选择最好的模型是：\", gc.best_estimator_) # 获取网格搜索（Grid Search）中找到的最优模型,这个最优模型是在所有参数组合中，交叉验证得分最高的模型。",
   "id": "fff66911ee50e0fd",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "选择最好的模型是： KNeighborsClassifier(n_neighbors=12, weights='distance')\n"
     ]
    }
   ],
   "execution_count": 120
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-12T08:46:55.675386Z",
     "start_time": "2025-01-12T08:46:55.669263Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# gc.cv_results_ 是 GridSearchCV 对象的一个属性，用于存储网格搜索的详细结果，它返回一个字典，包含每组参数组合的交叉验证结果、性能指标等信息\n",
    "print(\"每个超参数每次交叉验证的结果：\",gc.cv_results_)"
   ],
   "id": "b7b1817e1e6c6b33",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "每个超参数每次交叉验证的结果： {'mean_fit_time': array([0.01014328, 0.        , 0.0052317 , 0.0052073 , 0.00520611,\n",
      "       0.00520523, 0.0104146 , 0.00520714, 0.0052077 , 0.0104146 ,\n",
      "       0.01562349, 0.01562166, 0.        , 0.00520945, 0.0104142 ,\n",
      "       0.00521072]), 'std_fit_time': array([7.18287820e-03, 0.00000000e+00, 7.39873877e-03, 7.36423455e-03,\n",
      "       7.36254867e-03, 7.36131237e-03, 7.36423455e-03, 7.36400976e-03,\n",
      "       7.36479650e-03, 7.36423521e-03, 3.28252736e-06, 5.15042996e-07,\n",
      "       0.00000000e+00, 7.36726912e-03, 7.36395357e-03, 7.36906739e-03]), 'mean_score_time': array([0.20025198, 0.14026427, 0.2042466 , 0.09373911, 0.19786032,\n",
      "       0.0937403 , 0.18765839, 0.09893521, 0.19802086, 0.09372814,\n",
      "       0.18744294, 0.09893513, 0.203089  , 0.10934687, 0.20317864,\n",
      "       0.10934599]), 'std_score_time': array([1.66888479e-02, 2.14643442e-02, 6.76964980e-04, 1.27554300e-02,\n",
      "       7.35570237e-03, 3.05153015e-05, 3.09668463e-04, 7.36417835e-03,\n",
      "       7.47406656e-03, 3.70039836e-06, 1.28279142e-05, 7.36423455e-03,\n",
      "       1.23931803e-05, 2.83226822e-05, 1.49253204e-04, 4.46606360e-06]), 'param_n_neighbors': masked_array(data=[8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15,\n",
      "                   15],\n",
      "             mask=[False, False, False, False, False, False, False, False,\n",
      "                   False, False, False, False, False, False, False, False],\n",
      "       fill_value=999999), 'param_weights': masked_array(data=['uniform', 'distance', 'uniform', 'distance',\n",
      "                   'uniform', 'distance', 'uniform', 'distance',\n",
      "                   'uniform', 'distance', 'uniform', 'distance',\n",
      "                   'uniform', 'distance', 'uniform', 'distance'],\n",
      "             mask=[False, False, False, False, False, False, False, False,\n",
      "                   False, False, False, False, False, False, False, False],\n",
      "       fill_value=np.str_('?'),\n",
      "            dtype=object), 'params': [{'n_neighbors': 8, 'weights': 'uniform'}, {'n_neighbors': 8, 'weights': 'distance'}, {'n_neighbors': 9, 'weights': 'uniform'}, {'n_neighbors': 9, 'weights': 'distance'}, {'n_neighbors': 10, 'weights': 'uniform'}, {'n_neighbors': 10, 'weights': 'distance'}, {'n_neighbors': 11, 'weights': 'uniform'}, {'n_neighbors': 11, 'weights': 'distance'}, {'n_neighbors': 12, 'weights': 'uniform'}, {'n_neighbors': 12, 'weights': 'distance'}, {'n_neighbors': 13, 'weights': 'uniform'}, {'n_neighbors': 13, 'weights': 'distance'}, {'n_neighbors': 14, 'weights': 'uniform'}, {'n_neighbors': 14, 'weights': 'distance'}, {'n_neighbors': 15, 'weights': 'uniform'}, {'n_neighbors': 15, 'weights': 'distance'}], 'split0_test_score': array([0.46406619, 0.47730496, 0.46453901, 0.48061466, 0.46170213,\n",
      "       0.48014184, 0.45910165, 0.47777778, 0.45650118, 0.48108747,\n",
      "       0.45579196, 0.48085106, 0.45484634, 0.47825059, 0.45508274,\n",
      "       0.47895981]), 'split1_test_score': array([0.46275715, 0.47647198, 0.45566328, 0.4769449 , 0.45542681,\n",
      "       0.48238354, 0.4542445 , 0.48001892, 0.45329865, 0.48049184,\n",
      "       0.45471743, 0.4788366 , 0.45566328, 0.47860014, 0.44809648,\n",
      "       0.47623552]), 'split2_test_score': array([0.4599196 , 0.47789075, 0.46157484, 0.47836368, 0.4618113 ,\n",
      "       0.48191062, 0.46039253, 0.48332939, 0.45897375, 0.48332939,\n",
      "       0.46039253, 0.48427524, 0.46039253, 0.48262   , 0.46062899,\n",
      "       0.48049184]), 'mean_test_score': array([0.46224765, 0.47722257, 0.46059237, 0.47864108, 0.45964675,\n",
      "       0.48147867, 0.45791289, 0.48037536, 0.45625786, 0.48163623,\n",
      "       0.45696731, 0.48132097, 0.45696738, 0.47982358, 0.45460274,\n",
      "       0.47856239]), 'std_test_score': array([0.00173075, 0.00058214, 0.0036895 , 0.00151096, 0.00298428,\n",
      "       0.00096479, 0.00264694, 0.00228041, 0.00232323, 0.00122169,\n",
      "       0.0024614 , 0.00224504, 0.0024448 , 0.00198251, 0.00512762,\n",
      "       0.00176021]), 'rank_test_score': array([ 9,  8, 10,  6, 11,  2, 12,  4, 15,  1, 14,  3, 13,  5, 16,  7],\n",
      "      dtype=int32)}\n"
     ]
    }
   ],
   "execution_count": 118
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
